package dyyx;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Date;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.IntPoint;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.MultiPhraseQuery;
import org.apache.lucene.search.PhraseQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RegexpQuery;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.BytesRef;

public class QueryDemo {
	
    private static final String CONTENT = "content";


	public static void main(String[] args) throws Exception {
		System.out.println("hello,lucene Query,"+new Date());
	    String indexDir = FileUtil.INDEX_DIR;
		IndexReader indexReader = DirectoryReader.open(FSDirectory.open(Paths.get(indexDir)));
        IndexSearcher searcher = new IndexSearcher(indexReader);
        
        // MatchAllDocsQuery
        matchAllDocsQueryDemo(searcher);
        
        // TermQuery
        termQueryDemo(searcher);

        // BooleanQuery  must python but not snake
        booleanQueryDemo(searcher);
        // BooleanQuery must python and snake
        booleanQueryDemo2(searcher);

        // PhraseQuery
        phraseQueryDemo(searcher);
        phraseQuerySlop1(searcher);
        phraseQuerySlop2(searcher);
        phraseQuerySlop7(searcher);


        // MultiPhraseQuery
        multiPhraseQueryDemo(searcher);

        // PrefixQuery
        prefixQueryDemo(searcher);

        // WildcardQuery
        wildcardQueryDemo(searcher);

        // RegexpQuery
        regexpQueryDemo(searcher);

        // FuzzyQuery
        fuzzyQueryDemo(searcher);
        fuzzyQueryDemo2(searcher);


        // TermRangeQuery
        termRangeQueryDemo(searcher);

        // ConstantScoreQuery
        constantScoreQueryDemo(searcher);
        
        pointQueryDemo(searcher);

       
		
	}
	
	 private static void termQueryDemo(IndexSearcher searcher) throws IOException {
	        System.out.println("TermQuery python ");
	        TermQuery termQuery = new TermQuery(new Term(CONTENT, "python"));

	        printResult(searcher, termQuery);
	    }

	    private static void booleanQueryDemo(IndexSearcher searcher) throws IOException {
	        System.out.println("BooleanQuery, must python but not snake ");
	        BooleanQuery.Builder builder = new BooleanQuery.Builder();
	        builder.add(new TermQuery(new Term(CONTENT, "python")), BooleanClause.Occur.MUST);
	        builder.add(new TermQuery(new Term(CONTENT, "snake")), BooleanClause.Occur.MUST_NOT);
	        BooleanQuery booleanQuery = builder.build();

	        printResult(searcher, booleanQuery);
	    }
	    
	    private static void booleanQueryDemo2(IndexSearcher searcher) throws IOException {
	        System.out.println("BooleanQuery, must python and snake ");
	        BooleanQuery.Builder builder = new BooleanQuery.Builder();
	        builder.add(new TermQuery(new Term(CONTENT, "python")), BooleanClause.Occur.MUST);
	        builder.add(new TermQuery(new Term(CONTENT, "snake")), BooleanClause.Occur.MUST);
	        BooleanQuery booleanQuery = builder.build();

	        printResult(searcher, booleanQuery);
	    }

	    private static void phraseQueryDemo(IndexSearcher searcher) throws IOException {
	        System.out.println("PhraseQuery, quick fox");

	        PhraseQuery query = new PhraseQuery(CONTENT, "quick", "fox");

	        
	        printResult(searcher, query);
	    }

	    private static void phraseQuerySlop1(IndexSearcher searcher) throws IOException {
	        System.out.println("PhraseQuery slop 1 : quick fox ");
	        PhraseQuery query = new PhraseQuery(1, CONTENT, "quick", "fox");
	        printResult(searcher, query);
	    }
	    
	    private static void phraseQuerySlop2(IndexSearcher searcher) throws IOException {
	        System.out.println("PhraseQuery slop 2 : fox dog ");
	        PhraseQuery query = new PhraseQuery(2, CONTENT, "fox", "dog");
	        printResult(searcher, query);
	    }
	    
	    private static void phraseQuerySlop7(IndexSearcher searcher) throws IOException {
	        System.out.println("PhraseQuery slop 7 : fox dog ");
	        PhraseQuery query = new PhraseQuery(7, CONTENT, "fox", "dog");
	        printResult(searcher, query);
	    }

	    private static void multiPhraseQueryDemo(IndexSearcher searcher) throws IOException {
	        System.out.println("MultiPhraseQuery:");

	        MultiPhraseQuery.Builder builder = new MultiPhraseQuery.Builder();
	        Term[] termArray1 = new Term[2];
	        termArray1[0] = new Term(CONTENT, "quick");
	        termArray1[1] = new Term(CONTENT, "fox");
	        Term[] termArray2 = new Term[2];
	        termArray2[0] = new Term(CONTENT, "brown");
	        termArray2[1] = new Term(CONTENT, "fox");
	        builder.add(termArray1);
	        builder.add(termArray2);
	        MultiPhraseQuery multiPhraseQuery = builder.build();

	        printResult(searcher, multiPhraseQuery);
	    }

	    private static void prefixQueryDemo(IndexSearcher searcher) throws IOException {
	        System.out.println("PrefixQuery, ja");
	        PrefixQuery prefixQuery = new PrefixQuery(new Term(CONTENT, "ja"));

	        printResult(searcher, prefixQuery);
	    }

	    private static void wildcardQueryDemo(IndexSearcher searcher) throws IOException {
	        System.out.println("WildcardQuery, java*");
	        WildcardQuery wildcardQuery = new WildcardQuery(new Term(CONTENT, "java*"));

	        printResult(searcher, wildcardQuery);
	    }

	    private static void regexpQueryDemo(IndexSearcher searcher) throws IOException {
	        System.out.println("RegexpQuery, java.*");
	        RegexpQuery regexpQuery = new RegexpQuery(new Term(CONTENT, "java.*"));

	        printResult(searcher, regexpQuery);
	    }

	    private static void fuzzyQueryDemo(IndexSearcher searcher) throws IOException {
	        System.out.println("FuzzyQuery, jack");
	        FuzzyQuery fuzzyQuery = new FuzzyQuery(new Term(CONTENT, "jack"), 1);

	        printResult(searcher, fuzzyQuery);
	    }
	    
	    private static void fuzzyQueryDemo2(IndexSearcher searcher) throws IOException {
	        System.out.println("FuzzyQuery2, jack");
	        FuzzyQuery fuzzyQuery = new FuzzyQuery(new Term(CONTENT, "jack"), 2);

	        printResult(searcher, fuzzyQuery);
	    }


	    private static void termRangeQueryDemo(IndexSearcher searcher) throws IOException {
	        System.out.println("TermRangeQuery, java and jb");
	        TermRangeQuery termRangeQuery = new TermRangeQuery(CONTENT, new BytesRef("java"), new BytesRef("jb"), true, false);

	        printResult(searcher, termRangeQuery);
	    }

	    private static void constantScoreQueryDemo(IndexSearcher searcher) throws IOException {
	        System.out.println("ConstantScoreQuery java");
	        ConstantScoreQuery constantScoreQuery = new ConstantScoreQuery(
	                new FuzzyQuery(new Term(CONTENT, "java"), 1));

	        printResult(searcher, constantScoreQuery);
	    }

	    private static void matchAllDocsQueryDemo(IndexSearcher searcher) throws IOException {
	        System.out.println("MatchAllDocsQuery");
	        MatchAllDocsQuery matchAllDocsQuery = new MatchAllDocsQuery();

	        printResult(searcher, matchAllDocsQuery);
	    }
	    
	    private static void pointQueryDemo(IndexSearcher searcher) throws IOException {
	        System.out.println("pointQueryDemo length 30 90");
	        Query query = IntPoint.newRangeQuery("length2", 30, 90);

	        
	        printResult(searcher, query);
	    }

	    private static void printResult(IndexSearcher searcher, Query query) throws IOException {
	        TopDocs topDocs = searcher.search(query, 10);
	        if (topDocs.totalHits.value == 0) {
	            System.out.println("not found!\n");
	            return;
	        }

	        ScoreDoc[] hits = topDocs.scoreDocs;

	        System.out.println(topDocs.totalHits.value + " result(s) matched: ");
	        for (ScoreDoc hit : hits) {
	            Document doc = searcher.doc(hit.doc);
	            String str = "doc=" + hit.doc + " score=" + hit.score+",id="+doc.get("id")+",length="+doc.get("length");
	            str = str +",length2="+doc.get("length2");
	            str = str +",length3="+doc.get("length3");

	            System.out.println(str);
	        }
	        System.out.println();
	    }
}
